#pragma once

namespace Utility
{
	template<typename T>
	class singleton
	{
	public:
		static T* get_singleton()
		{
			if (nullptr != instance_)
			{
				instance_ = new (std::nothrow)T;
			}
			return instance_;
		}

		static void release_singleton()
		{
			if (nullptr != instance_)
			{
				delete instance_;
				instance_ = nullptr;
			}
		}

	protected:
		static T* instance_;
	};
}

#ifndef MAKE_SINGLETON
#define MAKE_SINGLETON(type, value) type* Utility::singleton<type>::instance_ = value;
#endif

#ifndef DECLARE_IMPLEMENTION
#define DECLARE_IMPLEMENTION         \
	private:                         \
		class Impl;                  \
		std::shared_ptr<Impl> impl_;
#endif
